using System;
using System.Globalization;
using System.Threading;
using System.Drawing;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Windows.Forms;

namespace needle.UI.Controls.Flat.Windows.Forms
{	
	[System.ComponentModel.ToolboxItem(true)]
	public class TextBox : needle.UI.Controls.Flat.Windows.Forms.ControlBase, needle.UI.Controls.Flat.Windows.Forms.IFlashabledControl
	{
		private TextBoxBase  m_pTextBox;
		private System.ComponentModel.IContainer components = null;
		private bool m_ReadOnly = false;
		private bool m_ShowErrorProvider = true;
		//Style Neo, default!!
		private Color m_TextColor = Color.Black;
		private Color m_EditDisabledColor = Color.FromArgb(238, 238, 225);
		private Color m_EditReadOnlyColor = Color.FromArgb(238, 238, 225);
		private Color m_EditFocusedColor = Color.White;
		private Color m_EditColor = Color.FromArgb(242, 242, 228);
		private Color m_NegativeNumberColor = Color.Black;
		private Color m_FlashColor = Color.FromArgb(170, 170, 221);

		[Category("Behavior")]
		public event ErrorOcurredEventHandler ErrorOcurred  = null;
		
		#region Constructors
		
		public TextBox()
		{
			InitializeComponent();
            m_pTextBox.TextChanged += new System.EventHandler(this.m_pTextBox_OnTextChanged);
			m_pTextBox.LostFocus       += new System.EventHandler(this.m_pTextBox_OnLostFocus);
			m_pTextBox.GotFocus        += new System.EventHandler(this.m_pTextBox_OnGotFocus);
			m_pTextBox.NumberOcurred   += new NumberOcurredEventHandler(this.m_pTextBox_NumberOcurred);
		}

		#endregion

		#region Dispose

		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null){
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#endregion

		#region Component Designer generated code

		private void InitializeComponent()
		{
			this.m_pTextBox = new needle.UI.Controls.Flat.Windows.Forms.TextBoxBase();
			this.SuspendLayout();
			// 
			// m_pTextBox
			// 
			this.m_pTextBox.Anchor = (System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right);
			this.m_pTextBox.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(242)), ((System.Byte)(242)), ((System.Byte)(228)));
			this.m_pTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
			this.m_pTextBox.DecimalPlaces = 2;
			this.m_pTextBox.DecMaxValue = 999999999;
			this.m_pTextBox.DecMinValue = -999999999;
			this.m_pTextBox.Location = new System.Drawing.Point(3, 1);
			this.m_pTextBox.Mask = needle.UI.Controls.Flat.Windows.Forms.EditMask.Custom;
			this.m_pTextBox.Name = "m_pTextBox";
			this.m_pTextBox.NotAcceptsChars = "";
			this.m_pTextBox.Required = false;
			this.m_pTextBox.Size = new System.Drawing.Size(94, 13);
			this.m_pTextBox.TabIndex = 0;
			this.m_pTextBox.Text = "";
			this.m_pTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.m_pTextBox_KeyDown);
			this.m_pTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.m_pTextBox_KeyPress);
			this.m_pTextBox.ErrorOcurred += new needle.UI.Controls.Flat.Windows.Forms.ErrorOcurredEventHandler(this.m_pTextBox_ErrorOcurred);
			this.m_pTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.m_pTextBox_KeyUp);
			this.m_pTextBox.NumberOcurred += new needle.UI.Controls.Flat.Windows.Forms.NumberOcurredEventHandler(this.m_pTextBox_NumberOcurred);
			this.m_pTextBox.TextChanged += new System.EventHandler(this.m_pTextBox_TextChanged);
			// 
			// TextBox
			// 
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.m_pTextBox});
			this.Name = "TextBox";
			this.Size = new System.Drawing.Size(100, 19);
			this.CausesValidationChanged += new System.EventHandler(this.TextBox_CausesValidationChanged);
			this.ResumeLayout(false);

		}

		#endregion

		#region Events handlers
				
		private void m_pTextBox_OnGotFocus(object sender, System.EventArgs e)
		{
			this.BackColor = this.m_EditFocusedColor;
			this.OnGotFocus(e);
		}

		private void m_pTextBox_OnTextChanged(object sender, System.EventArgs e) {
            this.OnTextChanged(e); 
        }

		private void m_pTextBox_OnLostFocus(object sender, System.EventArgs e)
		{
			this.BackColor = this.Style!=null?this.Style.InteliEditColor(this.ReadOnly,this.Enabled):
				             StyleGuide.InteliEditColor(this.ReadOnly,this.Enabled,this.m_EditColor, this.m_EditReadOnlyColor, this.m_EditDisabledColor);
			DrawControl(this.ContainsFocus);
			this.OnLostFocus(e);
		}

		private void m_pTextBox_TextChanged(object sender, System.EventArgs e)
		{
			this.OnTextChanged(e);
		}

		private void m_pTextBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			this.OnKeyDown(e);		
		}

		private void m_pTextBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
		{
			this.OnKeyPress(e);
		}

		private void m_pTextBox_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			this.OnKeyUp(e);
		}

		private void m_pTextBox_NumberOcurred(object sender, needle.UI.Controls.Flat.Windows.Forms.NumberOcurredEventArgs e)
		{
			e.NegativeNumberColor = this.m_NegativeNumberColor;
			e.PositiveNumberColor = this.m_TextColor;
		}

		private void m_pTextBox_ErrorOcurred(object sender, needle.UI.Controls.Flat.Windows.Forms.ErrorOcurredEventArgs e)
		{
			if (e.Message.Length > 0)
			{
				if (this.ErrorOcurred != null)
				{
					ErrorOcurredEventArgs oArg = new ErrorOcurredEventArgs(e.Message);
					ErrorOcurred(this, oArg); 
				}
			}
			//
			if (this.m_ShowErrorProvider) 
				base.Errors.SetError(this, e.Message);
		}

		private void TextBox_CausesValidationChanged(object sender, System.EventArgs e)
		{
			m_pTextBox.CausesValidation = this.CausesValidation;
		}

		#endregion

		#region Overrides

		protected override void OnEnterKeyPressed()
		{
			base.OnEnterKeyPressed();
			this.OnKeyDown(new KeyEventArgs(Keys.Enter));
			this.OnKeyPress(new KeyPressEventArgs((char)13));
		}

		protected override void OnStyleChanged(object sender, StyleEventArgs args)
		{
			base.OnStyleChanged(sender, args);

			if (args.PropertyName == "FlashColor") {this.FlashColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "TextColor") {this.TextColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "EditColor") {this.EditColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "EditFocusedColor") {this.EditFocusedColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "EditReadOnlyColor") {this.EditReadOnlyColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "EditDisabledColor") {this.EditDisabledColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "NegativeNumberColor") {this.NegativeNumberColor = (Color)args.PropertyValue;}

			this.BackColor = this.Style!=null? this.Style.InteliEditColor(this.m_pTextBox.ReadOnly,this.Enabled):
				StyleGuide.InteliEditColor(this.m_pTextBox.ReadOnly,this.Enabled,this.m_EditColor, this.m_EditReadOnlyColor, this.m_EditDisabledColor);
			
			this.Invalidate(true);
		}

		protected override void OnPlansOfColorsChanged(object sender, PlansOfColorsChangedEventArgs args)
		{
			base.OnPlansOfColorsChanged(sender, args);

			if (this.Style!=null)
			{
				this.FlashColor = this.Style.FlashColor;
				this.EditColor = this.Style.EditColor;
				this.EditFocusedColor = this.Style.EditFocusedColor;
				this.EditReadOnlyColor = this.Style.EditReadOnlyColor;
				this.EditDisabledColor = this.Style.EditDisabledColor;
				this.TextColor = this.Style.TextColor;
				this.NegativeNumberColor = this.Style.NegativeNumberColor;

				this.BackColor = this.Style!=null? this.Style.InteliEditColor(this.m_pTextBox.ReadOnly,this.Enabled):
					StyleGuide.InteliEditColor(this.m_pTextBox.ReadOnly,this.Enabled,this.m_EditColor, this.m_EditReadOnlyColor, this.m_EditDisabledColor);
			}

			this.Invalidate(true);
		}

		protected override void OnEnabledChanged(EventArgs e)
		{
			base.OnEnabledChanged(e);
			this.BackColor = this.Style!=null? this.Style.InteliEditColor(this.m_pTextBox.ReadOnly,this.Enabled):
				StyleGuide.InteliEditColor(this.m_pTextBox.ReadOnly,this.Enabled,this.m_EditColor, this.m_EditReadOnlyColor, this.m_EditDisabledColor);
		}

		#endregion

		#region Internal helpers

		private void ThreadFlashControl()
		{
			for (int i=1; i<=8;i++)
			{
				if(this.m_pTextBox.BackColor == this.EditColor)
				{
					this.m_pTextBox.BackColor = this.FlashColor;
				}
				else
				{
					this.m_pTextBox.BackColor = this.EditColor;
				}
				Thread.Sleep(150);
			}

			this.m_pTextBox.BackColor = this.EditColor;
		}

		#endregion

		#region Methods

		public bool ValidateZipNumber(string state)
		{
			return this.m_pTextBox.ValidateCep(state);
		}

		public bool ValidateStateRegistrationNumber(string state)
		{
			return this.m_pTextBox.ValidateInscricaoEstadual(state);
		}

		#endregion
		
		#region Properties

		[Browsable(false)]
		public bool ValidWithMask
		{
			get{return m_pTextBox.ValidWithMask;}
		}

        [Browsable(false)]
        public System.Windows.Forms.TextBox Me {
            get { return m_pTextBox; }
        }

		//2002-08-07 - GWO - Added to accept regular expressions.
		[Category("Behavior")]
		public string RegularExpression
		{
			get {return this.m_pTextBox.RegularExpression;}
			set {this.m_pTextBox.RegularExpression = value;}
		}

		//2002-08-24 - GWO - Added to accept custom messages.
		[Category("Behavior"),
		Localizable(true)]
		public string ErrorMessage
		{
			get {return m_pTextBox.ErrorMessage;}
			set {m_pTextBox.ErrorMessage = value;}
		}
		
		[Browsable(false),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new Color BackColor
		{
			get{ return base.BackColor; }

			set
			{
				base.BackColor      = value;
				if (m_pTextBox!=null) m_pTextBox.BackColor = value;
			}
		}

		[Browsable(false)]
		public override Color ForeColor
		{
			get{ return m_pTextBox.ForeColor; }

			set
			{
				base.ForeColor       = value;
				m_pTextBox.ForeColor = value;
			}
		}

		[Category("Style")]
		public Color TextColor
		{
			get {return m_TextColor;}
			set 
			{
				m_TextColor = value;
				this.m_pTextBox.ForeColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color FlashColor
		{
			get {return m_FlashColor;}
			set 
			{
				m_FlashColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color EditColor
		{
			get {return m_EditColor;}
			set 
			{
				m_EditColor = value;
				this.BackColor = value;
				this.m_pTextBox.BackColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color NegativeNumberColor
		{
			get {return m_NegativeNumberColor;}
			set 
			{
				m_NegativeNumberColor = value;
			}
		}

		[Category("Style")]
		public Color EditFocusedColor
		{
			get {return m_EditFocusedColor;}
			set 
			{
				m_EditFocusedColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color EditReadOnlyColor
		{
			get {return m_EditReadOnlyColor;}
			set 
			{
				m_EditReadOnlyColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color EditDisabledColor
		{
			get {return m_EditDisabledColor;}
			set 
			{
				m_EditDisabledColor = value;
				this.Invalidate();
			}
		}

		[Category("Behavior")]
		public EditMask Mask
		{
			get {return m_pTextBox.Mask;}
			set {m_pTextBox.Mask = value;}
		}

		[Category("Behavior")]
		public bool ShowErrorProvider
		{
			get {return m_ShowErrorProvider;}
			set {m_ShowErrorProvider = value;}
		}

		[Category("Behavior")]
		public bool Required
		{
			get	{return m_pTextBox.Required;}
			set	{m_pTextBox.Required = value;}
		}

		[Category("Behavior")]
		public int DecimalPlaces
		{
			get {return m_pTextBox.DecimalPlaces;}
			set {m_pTextBox.DecimalPlaces = value;}
		}

		[Category("Behavior")]
		public int DecMinValue
		{
			get {return m_pTextBox.DecMinValue;}
			set {m_pTextBox.DecMinValue = value;}
		}

		[Category("Behavior")]
		public int DecMaxValue
		{
			get {return m_pTextBox.DecMaxValue;}
			set {m_pTextBox.DecMaxValue = value;}
		}

		[Category("Behavior")]
		public string NotAcceptsChars
		{
			get {return m_pTextBox.NotAcceptsChars;}
			set {m_pTextBox.NotAcceptsChars = value;}
		}

		[Category("Behavior")]
		public int MaxLength
		{
			get {return m_pTextBox.MaxLength;}
			set {m_pTextBox.MaxLength = value;}
		}

		[Category("Behavior")]
		public char PasswordChar
		{
			get {return m_pTextBox.PasswordChar;}
			set {m_pTextBox.PasswordChar = value;}
		}

		[Category("Behavior")]
		public System.Windows.Forms.CharacterCasing CharacterCasing
		{
			get {return m_pTextBox.CharacterCasing;}
			set {m_pTextBox.CharacterCasing = value;}
		}

		[Category("Behavior")]
		public bool AcceptsReturn
		{
			get {return m_pTextBox.AcceptsReturn;}
			set {m_pTextBox.AcceptsReturn = value;}
		}

		[Category("Behavior")]
		public bool AcceptsTab
		{
			get {return m_pTextBox.AcceptsTab;}
			set {m_pTextBox.AcceptsTab = value;}
		}

		[Category("Behavior")]
		public bool HideSelection
		{
			get {return m_pTextBox.HideSelection;}
			set {m_pTextBox.HideSelection = value;}
		}

		[Category("Behavior")]
		public bool WordWrap
		{
			get {return m_pTextBox.WordWrap;}
			set {m_pTextBox.WordWrap = value;}
		}

		[Category("Behavior")]
		public bool Multiline
		{
			get {return m_pTextBox.Multiline;}
			set
			{ 
				m_pTextBox.Multiline     = value; 
				m_pTextBox.AcceptsReturn = true;
			}
		}

		[Category("Behavior")]
		public bool ReadOnly
		{
			get {return m_ReadOnly;}

			set 
			{
				m_ReadOnly = value;
				m_pTextBox.ReadOnly = value;

				if(value)
				{
					this.BackColor = this.EditReadOnlyColor;
				}
				else
				{
					if(this.ContainsFocus)
					{
						this.BackColor = this.EditFocusedColor;
					}
					else
					{
						this.BackColor = this.EditColor;
					}
				}
			}
		}

		[Category("Appearance")]
		public HorizontalAlignment TextAlign
		{
			get {return m_pTextBox.TextAlign;}
			set {m_pTextBox.TextAlign = value;}
		}

		[Category("Appearance")]
		public System.Windows.Forms.ScrollBars ScrollBars
		{
			get {return m_pTextBox.ScrollBars;}
			set {m_pTextBox.ScrollBars = value;}
		}

		[Category("Appearance")]
		public string[] Lines
		{
			get {return m_pTextBox.Lines;}
			set {m_pTextBox.Lines = value;}
		}

		[Bindable(true),
		Browsable(true),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
		Category("Appearance")]
		public override string Text
		{
			get {return m_pTextBox.Text;}
			set {m_pTextBox.Text = value;}
		}

		public new int Height
		{
			get {return base.Height;}

			set{
				if(value > m_pTextBox.Height + 1)
				{
					base.Height = value;
						
					if(!this.Multiline)
					{
						int yPos = (value - m_pTextBox.Height) / 2;
						m_pTextBox.Top = yPos;
					}
					else
					{
						m_pTextBox.Top    = 2;
						m_pTextBox.Height = this.Height - 4;
					}
				}
			}
		}

		public new Size Size
		{
			get {return base.Size;}

			set
			{
				if(value.Height > m_pTextBox.Height + 1)
				{					
					base.Size = value;

					if(!this.Multiline)
					{
						int yPos = (value.Height - m_pTextBox.Height) / 2;
						m_pTextBox.Top = yPos;
					}
					else
					{
						m_pTextBox.Top    = 2;
						m_pTextBox.Height = this.Height - 4;
					}
				}				
			}
		}

		[Browsable(false),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public double DecValue
		{
			get {return m_pTextBox.DoubleValue;}
			set {m_pTextBox.DoubleValue = value;}
		}

		[Browsable(false),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public bool IsModified
		{
			get {return m_pTextBox.Modified;}
			set {m_pTextBox.Modified = value;}
		}

		#endregion

		#region IFlashabledControl

		public void FlashControl()
		{
			Thread m_Thread = new Thread(new ThreadStart(ThreadFlashControl));
			m_Thread.Start();
		}
		
		#endregion
	}
}